package top.atcra.rpc.discovery.register;

import cn.hutool.core.lang.Pair;
import top.atcra.rpc.RPCBootstrap;
import top.atcra.rpc.discovery.register.impl.ZookeeperServiceRegistry;
import top.atcra.rpc.protection.health.ServiceUpAndDownWatcher;

/**
 * 描述如何基于连接字符串获取/创建注册中心
 *
 * @author atcra
 * @date 2025-3-22
 */
public class ServiceRegistryFactory {
    public enum RegistryType {
        ZOOKEEPER
    }

    public static ServiceRegistry getRegistry(String connectString) {
        var pair = getRegistryType(connectString);
        return switch (pair.getValue()) {
            case ZOOKEEPER -> new ZookeeperServiceRegistry(pair.getKey());
        };
    }

    /**
     * 创建注册中心，附带UpAndDownWatcher
     *
     * @param bootstrap     RPCBootstrap实例
     * @param connectString 连接字符串，格式为：registryType://address，例如zookeeper://127.0.0.1:2181
     * @return ServiceRegistry实例
     */
    public static ServiceRegistry getRegistry(RPCBootstrap bootstrap, String connectString) {
        var pair = getRegistryType(connectString);
        return switch (pair.getValue()) {
            case ZOOKEEPER -> new ZookeeperServiceRegistry(pair.getKey()).setCreateUpAndDownWatcher(
                    (o) -> new ServiceUpAndDownWatcher(bootstrap)
            );
        };
    }

    /**
     * 根据连接URL获取注册中心类型和地址
     *
     * @param connectURL 连接URL，格式为：registryType://address，例如zookeeper://127.0.0.1:2181
     * @return Pair<address, registryType>
     */
    private static Pair<String, RegistryType> getRegistryType(String connectURL) {
        var typeAndAddr = connectURL.split("://");
        RegistryType typ;
        if (typeAndAddr.length != 2) {
            throw new IllegalArgumentException("invalid registry url: " + connectURL);
        }
        try {
            typ = RegistryType.valueOf(typeAndAddr[0].toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("invalid registry url: " + connectURL);
        }
        return Pair.of(typeAndAddr[1], typ);
    }
}
